﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
    <meta http-equiv="expires" content="0" />
    <title>FaceCat-Html5</title>
</head>
<body>
    <canvas id="listCanvas" width="800" height="800" style="position: fixed; left: 0px; top: 0px;"/>
    <script type="text/javascript" src="facecat.js"></script>
    <script type="text/javascript">
        let canvasList = document.getElementById("listCanvas"); //绘图区域
        canvasList.width = window.innerWidth;
        canvasList.height = window.innerHeight;
        let paintList = new FCPaint(); //绘图对象
        paintList.canvas = canvasList;
        scaleCanvas(paintList);
        //判断主题色
        paintList.defaultUIStyle = "dark";
        let url = location.href;
        if (url.indexOf("color=light") != -1) {
            paintList.defaultUIStyle = "light";
        }
        //判断是否移动端
        paintList.isMobile = isMobileMode();
        if (paintList.isMobile) {
            paintList.scaleFactorX = 2.5;
            paintList.scaleFactorY = 2.5;
        }

        //面积图数据
        class ListData extends FCView {
            constructor() {
                super();
                this.value = 0; //数值
                this.key = null; //键
                this.open = 0; //第一个价格
                this.close = 0;
                super.viewType = "ldata"; //类型
            }
        };

        //创建图层
        let list = new FCDiv();

        //初始化图层
        let initDiv = function () {
            list.dock = "fill";
            //添加到框架
            addView(list, paintList);
            //根据主题配色
            if (list.paint.defaultUIStyle == "dark") {
                list.backColor = "rgb(0,0,0)";
            } else if (list.paint.defaultUIStyle == "light") {
                list.backColor = "rgb(255,255,255)";
            }
            list.borderColor = null;
            list.text = "图层";
            list.viewName = "list";
            list.showVScrollBar = true;

            list.useAnimation = true;
            list.itemHeight = 60;
            list.rects = new Array();
        };

        initDiv();

        /*
        * 动画秒表
        */
        let onListTime = function (list) {
            let paint2 = false;
            if (list.useAnimation) {
                for (let i = 0; i < list.rects.length; i++) {
                    let subView = list.views[i];
                    let targetRect = list.rects[i];
                    let nowRect = new FCRect(subView.location.x, subView.location.y, subView.location.x + subView.size.cx, subView.location.y + subView.size.cy);
                    let isMove = false;
                    if (true) {
                        if (nowRect.left > targetRect.left) {
                            nowRect.left -= (nowRect.left - targetRect.left) / 4;
                            if (nowRect.left - targetRect.left < 10) {
                                nowRect.left = targetRect.left;
                            }
                            paint2 = true;
                        }
                        else if (nowRect.left < targetRect.left) {
                            nowRect.left += (targetRect.left - nowRect.left) / 4;
                            if (targetRect.left - nowRect.left < 10) {
                                nowRect.left = targetRect.left;
                            }
                            paint2 = true;
                        }
                    }

                    if (true) {
                        if (nowRect.top > targetRect.top) {
                            nowRect.top -= (nowRect.top - targetRect.top) / 4;
                            if (nowRect.top - targetRect.top < 10) {
                                nowRect.top = targetRect.top;
                            }
                            isMove = true;
                            paint2 = true;
                        }
                        else if (nowRect.top < targetRect.top) {
                            nowRect.top += (targetRect.top - nowRect.top) / 4;
                            if (targetRect.top - nowRect.top < 10) {
                                nowRect.top = targetRect.top;
                            }
                            paint2 = true;
                        }
                    }

                    if (true) {
                        if (nowRect.right > targetRect.right) {
                            nowRect.right -= (nowRect.right - targetRect.right) / 4;
                            if (nowRect.right - targetRect.right < 10) {
                                nowRect.right = targetRect.right;
                            }
                            paint2 = true;
                        }
                        else if (nowRect.right < targetRect.right) {
                            nowRect.right += (targetRect.right - nowRect.right) / 4;
                            if (targetRect.right - nowRect.right < 10) {
                                nowRect.right = targetRect.right;
                            }
                            paint2 = true;
                        }
                    }
                    if (true) {
                        if (nowRect.bottom > targetRect.bottom) {
                            nowRect.bottom -= (nowRect.bottom - targetRect.bottom) / 4;
                            if (nowRect.bottom - targetRect.bottom < 10) {
                                nowRect.bottom = targetRect.bottom;
                            }
                            paint2 = true;
                        }
                        else if (nowRect.bottom < targetRect.bottom) {
                            nowRect.bottom += (targetRect.bottom - nowRect.bottom) / 4;
                            if (targetRect.bottom - nowRect.bottom < 10) {
                                nowRect.bottom = targetRect.bottom;
                            }
                            paint2 = true;
                        }
                    }
                    subView.isMove = isMove;
                    subView.location = new FCPoint(nowRect.left, nowRect.top);
                    subView.size = new FCSize(nowRect.right - nowRect.left, nowRect.bottom - nowRect.top);
                }
            } else {
                for (let i = 0; i < list.rects.length; i++) {
                    let subView = list.views[i];
                    let targetRect = list.rects[i];
                    subView.location = new FCPoint(targetRect.left, targetRect.top);
                    subView.size = new FCSize(targetRect.right - targetRect.left, targetRect.bottom - targetRect.top);
                }
            }
            if (paint2) {
                invalidateView(list);
            }
        };

        /*
        * 点击方法
        * view:视图
        * firstTouch:是否第一次触摸
        * firstPoint:第一次触摸的坐标
        * secondTouch:是否第二次触摸
        * secondPoint:第二次触摸的坐标
        * clicks:点击次数
        */
        let onClick_Div = function (view, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
            onClickDefault(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
        };

        /*
        * 鼠标按下实现方法
        * view:视图
        * mp:坐标
        * button:按钮
        * clicks:点击次数
        * delta:滚轮值
        */
        let onMouseDown_Div = function (view, mp, buttons, clicks, delta) {
            onMouseDownDefault(view, mp, buttons, clicks, delta);
            if (view.viewType == "ldata") {
                let firstTouch = false, secondTouch = false;
                let firstPoint = mp, secondPoint = mp;
                if (buttons == 1) {
                    firstTouch = true;
                }
                touchDownDiv(view.parent, firstTouch, firstPoint, secondTouch, secondPoint);
            }
        };

        /*
        * 鼠标滚动实现方法
        * view:视图
        * mp:坐标
        * button:按钮
        * clicks:点击次数
        * delta:滚轮值
        */
        let onMouseWheel_Div = function (view, mp, buttons, clicks, delta) {
            if (window.event.ctrlKey && view.paint) {
                //放大显示
                if (delta < 0) {
                    view.paint.scaleFactorX = view.paint.scaleFactorX + 0.1;
                    view.paint.scaleFactorY = view.paint.scaleFactorY + 0.1;
                    resizeAll();
                    //缩小显示
                } else if (delta > 0) {
                    if (view.paint.scaleFactorX > 0.2) {
                        view.paint.scaleFactorX = view.paint.scaleFactorX - 0.1;
                        view.paint.scaleFactorY = view.paint.scaleFactorY - 0.1;
                        resizeAll();
                    }
                }
                return;
            }
            onMouseWheelDefault(view, mp, buttons, clicks, delta);
            if (view.viewType == "ldata") {
                touchWheelDiv(view.parent, delta);
                invalidateView(view.parent);
            }
        };

        /*
        * 触摸开始方法
        * view:视图
        * firstTouch:是否第一次触摸
        * firstPoint:第一次触摸的坐标
        * secondTouch:是否第二次触摸
        * secondPoint:第二次触摸的坐标
        */
        let onTouchBegin_Div = function (view, firstTouch, firstPoint, secondTouch, secondPoint) {
            onTouchBeginDefault(view, firstTouch, firstPoint, secondTouch, secondPoint);
            if (view.viewType == "ldata") {
                view.parent.allowDragScroll = true;
                touchDownDiv(view.parent, firstTouch, firstPoint, secondTouch, secondPoint);
            }
        };

        /*
        * 触摸移动方法
        * view:视图
        * firstTouch:是否第一次触摸
        * firstPoint:第一次触摸的坐标
        * secondTouch:是否第二次触摸
        * secondPoint:第二次触摸的坐标
        */
        let onTouchMove_Div = function (view, firstTouch, firstPoint, secondTouch, secondPoint) {
            onTouchMoveDefault(view, firstTouch, firstPoint, secondTouch, secondPoint);
            if (view.viewType == "ldata") {
                touchMoveDiv(view.parent, firstTouch, firstPoint, secondTouch, secondPoint);
                invalidateView(view.parent);
            }
        };

        /*
        * 触摸结束方法
        * view:视图
        * firstTouch:是否第一次触摸
        * firstPoint:第一次触摸的坐标
        * secondTouch:是否第二次触摸
        * secondPoint:第二次触摸的坐标
        */
        let onTouchEnd_Div = function (view, firstTouch, firstPoint, secondTouch, secondPoint) {
            onTouchEndDefault(view, firstTouch, firstPoint, secondTouch, secondPoint);
            if (view.viewType == "ldata") {
                touchUpDiv(view.parent, firstTouch, firstPoint, secondTouch, secondPoint);
                invalidateView(view.parent);
            }
        };

        /*
        * 鼠标移动实现方法
        * view:视图
        * mp:坐标
        * button:按钮
        * clicks:点击次数
        * delta:滚轮值
        */
        let onMouseMove_Div = function (view, mp, buttons, clicks, delta) {
            onMouseMoveDefault(view, mp, buttons, clicks, delta);
            if (view.viewType == "ldata") {
                let firstTouch = false, secondTouch = false;
                let firstPoint = mp, secondPoint = mp;
                if (buttons == 1) {
                    firstTouch = true;
                }
                touchMoveDiv(view.parent, firstTouch, firstPoint, secondTouch, secondPoint);
                invalidateView(view.parent);
            }
        };

        /*
        * 鼠标抬起实现方法
        * view:视图
        * mp:坐标
        * button:按钮
        * clicks:点击次数
        * delta:滚轮值
        */
        let onMouseUp_Div = function (view, mp, buttons, clicks, delta) {
            onMouseUpDefault(view, mp, buttons, clicks, delta);
            if (view.viewType == "ldata") {
                let firstTouch = false, secondTouch = false;
                let firstPoint = mp, secondPoint = mp;
                if (buttons == 1) {
                    firstTouch = true;
                }
                touchUpDiv(view.parent, firstTouch, firstPoint, secondTouch, secondPoint);
            }
        };

        /*
        * 绘制数据项
        */
        let drawListItem = function (view, paint, clipRect) {
            let scrollV = view.parent.scrollV;
            if (view.location.y + view.size.cy - scrollV >= 0 && view.location.y - scrollV < view.parent.size.cy) {
                let totalValue = view.parent.totalValue;
                let diffRange = ((view.close - view.open) / view.clode * 100).toFixed(2) + "%";
                let rtRight = (view.size.cx - 130) * view.value / totalValue;
                if (view.backColor) {
                    paint.fillRect(view.backColor, 0, 10 - scrollV + view.location.y, rtRight, view.size.cy - 10 - scrollV + view.location.y);
                }
                if (view.borderColor) {
                    paint.drawRect(view.borderColor, 1, 0, 0, 10 - scrollV + view.location.y, rtRight, view.size.cy - 10 - scrollV + view.location.y);
                }
                rtRight += 10;
                let fontSize1 = parseInt(Math.min(view.size.cx, view.size.cy) / 4);
                if (fontSize1 > 1) {
                    let baseUpper = "Code1";
                    let font1 = "Default," + fontSize1;
                    let tSize = paint.textSize(baseUpper, font1);
                    let quoteUpper = "Code2";
                    let font2 = "Default," + (fontSize1 / 2);
                    let tSize2 = paint.textSize(quoteUpper, font2);

                    if (view.paint.defaultUIStyle == "dark") {
                        paint.drawText(baseUpper, "rgb(255,255,255)", font1, rtRight, view.size.cy / 2 - tSize.cy + 2 - scrollV + view.location.y - tSize.cy / 2);
                        paint.drawText(quoteUpper, "rgb(255,255,255)", font2, rtRight, view.size.cy / 2 + 2 - scrollV + view.location.y - tSize2.cy / 2);
                    } else if (view.paint.defaultUIStyle == "light") {
                        paint.drawText(baseUpper, "rgb(0,0,0)", font1, rtRight, view.size.cy / 2 - tSize.cy + 2 - scrollV + view.location.y - tSize.cy / 2);
                        paint.drawText(quoteUpper, "rgb(0,0,0)", font2, rtRight, view.size.cy / 2 + 2 - scrollV + view.location.y - tSize2.cy / 2);
                    }

                    let strPrice = view.close.toFixed(6);
                    let font3 = "Default," + (fontSize1 * 2 / 3);
                    let tSize5 = paint.textSize(strPrice, font3);
                    if (view.paint.defaultUIStyle == "dark") {
                        paint.drawText(strPrice, "rgb(255,255,255)", font3, rtRight, view.size.cy / 2 + tSize.cy + 2 - scrollV + view.location.y - tSize5.cy / 2);
                    } else if (view.paint.defaultUIStyle == "light") {
                        paint.drawText(strPrice, "rgb(0,0,0)", font3, rtRight, view.size.cy / 2 + tSize.cy + 2 - scrollV + view.location.y - tSize5.cy / 2);
                    }
                }
            }
        };

        /*
        * 重绘背景的实现方法
        * view:视图
        * paint:绘图对象
        * clipRect:裁剪区域
        */
        paintList.onPaint = function (view, paint, clipRect) {
            if (view.viewName == "list") {
                paint.fillRect(view.backColor, 0, 0, view.size.cx, view.size.cy)
                for (let i = 0; i < view.views.length; i++) {
                    if (!view.views[i].isMove) {
                        drawListItem(view.views[i], paint, clipRect);
                    }
                }
            }
            else if (view.viewType == "ldata") {
            }
            else {
                onPaintDefault(view, paint, clipRect);
            }
        };

        /*
        * 重绘边框的实现方法
        * view:视图
        * paint:绘图对象
        * clipRect:裁剪区域
        */
        paintList.onPaintBorder = function (view, paint, clipRect) {
            if (view.viewName == "list") {
                for (let i = 0; i < view.views.length; i++) {
                    if (view.views[i].isMove) {
                        drawListItem(view.views[i], paint, clipRect);
                    }
                }
                drawDivScrollBar(view, paint, clipRect);
            } else if (view.viewType == "ldata") {
            } else {
                onPaintBorderDefault(view, paint, clipRect);
            }
        };

        /*
         * 更新布局的实现方法
         * views:视图集合
         */
        paintList.onUpdateView = function (views) {
            updateViewDefault(views);
        }

        //注册事件
        addMouseDownEvent(canvasList, paintList, onMouseDown_Div);
        addMouseMoveEvent(canvasList, paintList, onMouseMove_Div);
        addMouseWheelEvent(canvasList, paintList, onMouseWheel_Div);
        addMouseUpEvent(canvasList, paintList, onMouseUp_Div, onClick_Div);
        addTouchBeginEvent(canvasList, paintList, onTouchBegin_Div);
        addTouchMoveEvent(canvasList, paintList, onTouchMove_Div);
        addTouchEndEvent(canvasList, paintList, onTouchEnd_Div, onClick_Div);

        /*
         * 重置大小
         */
        let resizeAll = function () {
            canvasList.width = document.documentElement.clientWidth;
            canvasList.height = document.documentElement.clientHeight;
            scaleCanvas(paintList);
            updateViewDefault(paintList.views);
            invalidate(paintList);
        };

        /*
        * 监听大小改变
        */
        window.onresize = function () {
            resizeAll();
        };

        /*
        * 旋转监听
        */
        window.onorientationchange = function () {
            resizeAll();
        };

        /*
        * 更新列表
        */
        let updateList = function (list) {
            list.rects = new Array();
            let viewsSize = list.views.length;
            for (let i = 0; i < viewsSize; i++) {
                let thisCell = list.views[i];
                list.rects.push(new FCRect(0, i * list.itemHeight, list.size.cx - list.scrollSize, (i + 1) * list.itemHeight));
            }
        };


        let allowPaint_List = false;

        /*
        * 检查绘图
        */
        let checkListPaint = function () {
            updateList(list);
            onListTime(list);
            resizeAll();
        };

        //启动秒表
        setInterval(checkListPaint, 50);

        //定义颜色
        let listColors = new Array();
        listColors.push("rgb(59,174,218)");
        listColors.push("rgb(185,63,150)");
        listColors.push("rgb(219,68,83)");
        listColors.push("rgb(246,187,67)");
        listColors.push("rgb(216,112,173)");
        listColors.push("rgb(140,192,81)");
        listColors.push("rgb(233,87,62)");
        listColors.push("rgb(150,123,220)");
        listColors.push("rgb(75,137,220)");
        listColors.push("rgb(170,178,189)");

        for (let i = 0; i < 100; i++) {
            let pData = new ListData;
            pData.key = i;
            pData.text = i;
            pData.value = Math.random() * 900 + 100;
            pData.open = Math.random() * 90 + 10;
            pData.close = Math.random() * 90 + 10;
            pData.size = new FCSize(list.size.cx, list.itemHeight);
            pData.location = new FCPoint(0, list.views.length * list.itemHeight);
            pData.backColor = listColors[list.views.length % listColors.length];
            pData.paint = paintList;
            if (list.paint.defaultUIStyle == "dark") {
                pData.borderColor = "rgb(255,255,255)";
            } else if (list.paint.defaultUIStyle == "light") {
                pData.borderColor = "rgb(0,0,0)";
            }
            pData.visible = true;
            pData.parent = list;
            list.views.push(pData);
        }
        let totalValue = 0;
        viewsSize = list.views.length;
        for (let i = 0; i < viewsSize; i++) {
            let thisCell = list.views[i];
            if (totalValue < thisCell.value) {
                totalValue = thisCell.value;
            }
        }
        list.totalValue = totalValue;
        list.views.sort((m, n) => {
            if (m.value > n.value) {
                return -1;
            }
            else if (m.value < n.value) {
                return 1;
            }
            else return 0;
        });
        updateViewDefault(paintList.views);
        //刷新界面
        invalidate(paintList);
    </script>
</body>
</html>
